﻿// Out of Hay POJ - 2395.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <algorithm>

using namespace std;
//https://vjudge.csgrandeur.cn/problem/POJ-2395

/*
奶牛们的干草用完了，这是一件必须立即补救的可怕事件。贝西打算走访其他农场，调查它们的干草情况。
一共有 N（2 <= N <= 2,000）个农场（编号为 1...N）；贝西从农场 1 开始。
她将穿越连接农场的 M（1 <= M <= 10,000 条）条长度不超过 1,000,000,000 的双向道路中的部分或全部道路。
有些农场可能有多条不同长度的道路相连。所有农场都以这种或那种方式与农场 1 相连。

贝西正在考虑需要多大的水皮。她知道每单位长度的道路需要一盎司水。因为她可以在每个农场得到更多的水，所以她只关心最长道路的长度。
当然，她在规划农场之间的路线时，会尽量减少必须携带的水量。

请帮助贝西了解她所要携带的最大水量：假设她选择的路线是最小的，那么她在任何两个农场之间要走的最长的路的长度是多少？
当然，这意味着她可能会在一条路上走回头路，以尽量减少她要走的最长道路的长度。
输入
* 第 1 行： 两个空格分隔的整数 N 和 M。

* 第 2..1+M 行：第 i+1 行包含三个空格分隔的整数 A_i、B_i 和 L_i，描述了一条从 A_i 到 B_i 长度为 L_i 的道路。
输出
* 第 1 行： 一个整数，即需要穿越的最长道路的长度。

样本
3 3
1 2 23
2 3 1000
1 3 43

43

提示
为了到达 2 号农场，贝西沿着长度为 23 的道路行驶。为了到达 3 号农场，贝西沿着一条长度为 43 的道路行驶。
贝西的油箱容量为 43，只要她在出发前将油箱加满至最大容量，她就能沿着这些道路行驶。
*/


const int N = 2010;
const int M = 10010;
int f[N];
struct Edge     // 存储边
{
    int a, b, w;

    bool operator< (const Edge& W)const
    {
        return w < W.w;
    }
}edges[M];
int n, m;

int find(int x)     // 并查集核心操作
{
    if (f[x] != x) f[x] = find(f[x]);
    return f[x];
}

void init() {
    for (int i = 0; i <= n; i++) f[i] = i;
}

int solve() {
    sort(edges, edges + m);
    init();

    int maxlen = -1;
    int res = 0, cnt = 0;
    for (int i = 0; i < m; i++) {
        int a = edges[i].a, b = edges[i].b, w = edges[i].w;
        a = find(a), b = find(b);
        if (a != b) {
            f[a] = b;
            res += w;
            maxlen = max(maxlen, w);
            cnt++;
        }
    }

    return maxlen;
}



int main()
{
    cin >> n >> m;
    for (int i = 0; i < m; i++) {
        cin >> edges[i].a >> edges[i].b >> edges[i].w;
    }

    cout << solve() << endl;

	return 0;
}

